<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>三维场景</title>
    <style>
      body {
        margin: 0;
        overflow: hidden;
        /* 隐藏body窗口区域滚动条 */
      }
    </style>
  </head>
  <body>
    <script type="importmap">
      {
        "imports": {
          "three": "./three.js-dev/build/three.module.js",
          "three/addons/": "./three.js-dev/examples/jsm/"
        }
      }
    </script>
    <script type="module">
      import * as THREE from 'three'
      import { OrbitControls } from 'three/addons/controls/OrbitControls.js'
      window.THREE = THREE
      // 创建场景对象
      var scene = new THREE.Scene()
      // 创建网格模型
      var geometry = new THREE.SphereGeometry(60, 40, 40) // 球体几何对象
      var geometry2 = new THREE.BoxGeometry(40, 100, 40) // 立方体几何对象
      // 漫反射 材质 	wireframe将几何图形渲染为线框。 默认值为false
      var meshLambertMaterial = new THREE.MeshLambertMaterial({
        color: 0x0000ff,
        // opacity: 1,
        // transparent: true,
        // wireframe: true,
      })
      // 镜面反射 材质
      var meshPhongMaterial = new THREE.MeshPhongMaterial({
        color: 0x0000ff,
        specular: 0x4488ee, //球体网格模型的高光颜色
        shininess: 12, //光照强度的系数
      })
      // 点材质
      var materialPoint = new THREE.PointsMaterial({
        color: 0x0000ff,
        size: 3,
      })
      // 线材质
      var lineMaterial = new THREE.LineBasicMaterial({
        color: 0x0000fff,
      })
      // 虚线材质
      var dashLineMaterial = new THREE.LineDashedMaterial({
        color: 0x0000ff,
        dashSize: 10,//显示线段的大小。默认为3。
        gapSize: 5//间隙的大小。默认为1
      })
      // 基础网格材质
      var basicMeshMaterial = new THREE.MeshBasicMaterial({
        color: 0x0000ff
      })
      var mesh_sphere = new THREE.Mesh(geometry, meshLambertMaterial) // 网格模型对象
      var mesh_Box = new THREE.Mesh(geometry2, meshLambertMaterial) // 网格模型对象
      // mesh.translateY(120)
      // scene.add(mesh_sphere)
      scene.add(mesh_Box)

      // 设置产生投影的网格模型
      mesh_Box.castShadow = true;

      // 平面几何体作为投影面
      let planeGeometry = new THREE.PlaneGeometry(300,200)
      let planeMaterial = new THREE.MeshLambertMaterial({
        color: 0x999999
      })
      let planeMesh = new THREE.Mesh(planeGeometry,planeMaterial)
      planeMesh.rotateX(-Math.PI/2)
      planeMesh.position.y = -50
      // 设置接收阴影的投影面
      planeMesh.castShadow = true
      planeMesh.receiveShadow = true
      scene.add(planeMesh)
 
      // 辅助坐标系  参数250表示坐标系大小，可以根据场景大小去设置
      let axesHelper = new THREE.AxesHelper(250)
      scene.add(axesHelper)

    

      // 光源设置
      var point = new THREE.PointLight(0xffffff)
      point.position.set(160, 100, 140) // 点光源位置
      // scene.add(point) //点光源添加到场景中



      // 平行光
      var directionalLight = new THREE.DirectionalLight(0xffffff,1)
      directionalLight.position.set(60, 100, 40)
      directionalLight.target = mesh_Box
      directionalLight.castShadow = true;
      directionalLight.shadow.camera.near = 0.5;
      directionalLight.shadow.camera.far = 300;
      directionalLight.shadow.camera.left = -50;
      directionalLight.shadow.camera.right = 50;
      directionalLight.shadow.camera.top = 200;
      directionalLight.shadow.camera.bottom = -100;
      directionalLight.shadow.mapSize.set(1024,1024)// 设置mapSize属性可以使阴影更清晰，不那么模糊
      // scene.add(directionalLight)

      // 光源辅助对象
      let pointLightHelper = new THREE.DirectionalLightHelper(directionalLight,150,'yellow')
      // scene.add(pointLightHelper)

      // 聚光光源
      var spotLight = new THREE.SpotLight(0xffffff)
      spotLight.position.set(50,90,50)
      spotLight.angle = Math.PI/6
      scene.add(spotLight)
      spotLight.castShadow = true
      spotLight.shadow.camera.near = 1
      spotLight.shadow.camera.far = 300
      spotLight.shadow.camera.fov = 20

      // 光源辅助对象
      let spotLightHelper = new THREE.SpotLightHelper(spotLight,'yellow')
      scene.add(spotLightHelper)

      //环境光
      var ambient = new THREE.AmbientLight(0x444444)
      scene.add(ambient)
 

      // 相机设置
      var width = window.innerWidth
      var height = window.innerHeight
      var k = width / height
      var s = 200 //三维场景显示范围控制系数，系数越大，显示的范围越大
      //创建相机对象
      var camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000)
      camera.position.set(200, 300, 200) //设置相机位置
      camera.lookAt(scene.position) //设置相机方向(指向的场景对象)

      // 创建渲染器对象
      var renderer = new THREE.WebGLRenderer()
      renderer.setSize(width, height) //设置渲染区域尺寸
      renderer.setClearColor(0xb9d3ff, 1) //设置背景颜色
      renderer.shadowMap.enabled = true // 开启阴影渲染
      document.body.appendChild(renderer.domElement) //body元素中插入canvas对象

      let T0 = 0
      // function render(ct) {
      //   if (!T0) {
      //     T0 = ct
      //   }
      //   let T1 = ct
      //   let t = (T1 - T0).toFixed() //时间差
      //   T0 = ct //把本次时间赋值给上次时间
      //   renderer.render(scene, camera)
      //   mesh_Box.rotateY(0.001 * t)
      //   // mesh2.rotateY(0.001 * t)
      //   requestAnimationFrame(render) //请求再次执行渲染函数render
      // }
      // requestAnimationFrame(render) //周期性执行render函数，没必要再通过监听鼠标事件执行render函数
      // mesh2.rotateY(Math.PI/2)
      renderer.render(scene, camera)
      function renderScene(){
        renderer.render(scene, camera)
      }
      let controls = new OrbitControls(camera, renderer.domElement) //创建控件对象
      controls.addEventListener('change',renderScene) //监听鼠标，键盘事件
    </script>
  </body>
</html>
